
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "crc32.h"

static void printHex(uint32_t value)
{
    uint8_t hex[4] = {0};
    memcpy(hex, &value, 4);
}

/**
 * argv 说明：
 * argv[1]: 原始文件路径
 * argv[2]: 软件版本号 
 */
int main(int argc, char **argv)
{
    uint8_t covertBuffer[8192] = {0};
    uint32_t readLen = 0;

    /* header msg */
    uint8_t imgHeader[20] = {0};
    uint8_t version = 0;
    uint32_t crcValue = 0;
    uint32_t originTotalLen = 0;
    uint8_t crcHex[4] = {0};
    uint8_t totalHex[4] = {0};

    /* file msg */
    char objectFileName[20] = {0};
    char *originFileName = NULL;
    FILE *fpOrigin = NULL;
    FILE *fpObject = NULL;

    /* 判断输入参数是否合法 */
    if (argc != 3)
    {
        printf("param error, eg: xx.out [origin bin path] [sw version]\n");
        return 0;
    }

    originFileName = argv[1];
    strcpy(objectFileName, "DoorLockAppUpdate_v");
    strcat(objectFileName, argv[2]);
    strcat(objectFileName, ".bin");
    version = atoi(argv[2]);

    printf("== pre convent ==\n");
    printf("origin file: %s\n", argv[1]);
    printf("sw version: %s, hex: [0x%x]\n", argv[2], version);
    printf("object file: %s\n", objectFileName);
    printf("\n");

    printf("== calculate crc value ==\n");
    fpOrigin = fopen(originFileName, "rb");
    fpObject = fopen(objectFileName, "wb+");

    if (fpOrigin == NULL || fpOrigin == NULL)
    {
        printf("open file error\n");
        return 0;
    }

    /* 从原始文件读取数据, 计算crc, 并将读取的数据写入新文件 */
    while (1)
    {
        readLen = fread(covertBuffer, 1, sizeof(covertBuffer), fpOrigin);

        if (readLen > 0)
        {
            originTotalLen += readLen;

            printf("read len: %u\n", readLen);

            crcValue = Crc32Compute(crcValue, covertBuffer, readLen);
        }
        else
        {
            printf("origin file crc over\n");

            memcpy(totalHex, &originTotalLen, 4);
            for (int i=0; i<2; i++)
            {
                uint8_t tmp;
                tmp = totalHex[i];
                totalHex[i] = totalHex[3-i];
                totalHex[3-i] = tmp;
            }
            printf("total len dec: %u; ", originTotalLen);
            printf("total len hex: 0x%02x%02x%02x%02x\n", totalHex[0], totalHex[1], totalHex[2], totalHex[3]);

            memcpy(crcHex, &crcValue, 4);
            for (int i=0; i<2; i++)
            {
                uint8_t tmp;
                tmp = crcHex[i];
                crcHex[i] = crcHex[3-i];
                crcHex[3-i] = tmp;
            }
            printf("crc value dec: %u; ", crcValue);
            printf("crc value hex: 0x%02x%02x%02x%02x\n", crcHex[0], crcHex[1], crcHex[2], crcHex[3]);
            break;
        }
    }
    printf("\n");

    printf("== write into object file ==\n");
    memcpy(imgHeader, "LuopingDL", 9);
    imgHeader[9] = version;
    imgHeader[10] = 0xff;
    imgHeader[11] = 0xff;
    memcpy(imgHeader+12, crcHex, 4);
    memcpy(imgHeader+16, totalHex, 4);

    printf("img hdr: \n");
    for (int i=0; i<sizeof(imgHeader); i++)
    {
        printf("%02x ", imgHeader[i]);
    }

    /* 写入头 */
    fwrite(imgHeader, 1, sizeof(imgHeader), fpObject);

    /* 写入原始文件 */
    fseek(fpOrigin, 0, SEEK_SET);

    while (1)
    {
        readLen = fread(covertBuffer, 1, sizeof(covertBuffer), fpOrigin);

        if (readLen > 0)
        {
            if (readLen % 4 != 0)
            {
                readLen = 4 * (readLen/4 + 1);
            }

            fwrite(covertBuffer, 1, readLen, fpObject);
        }
        else
        {
            printf("object file write over\n");
            break;
        }
    }
    printf("\n");

    printf("== complete ==\n");
    fclose(fpOrigin);
    fclose(fpObject);
    printf("\n");

    return 0;
}

